/***********************************************************************************
 * @author Luochengbang 2014/11/18
   可编辑下拉菜单
   filter="id,orgName"      需要过滤的列名
   filttype="or"            过滤的模式{and 或 or}
   ajax=""                  从后台异步请求数据
   datavalue="id:序号"      绑定value列
   datatext="orgName:部门"  绑定Text列
   columns='[{orgNum:"部门编码",parent:"上司"}]' 其他列
   ref =                    联动下级
   refUrl =                 联动下级异步请求后台数据
   noValue=false            不显示值列，默认显示
************************************************************************************/

(function ($) {
    var allSelectBox = [];
    var select3keys = { up: 38, down: 40, enter: 13, tab: 9, esc: 27 };
    var killAllBox = function (bid) {
        $.each(allSelectBox, function (i) {
            if (allSelectBox[i] != bid) {
                if (!$("#" + allSelectBox[i])[0]) {
                    $("#div_" + allSelectBox[i]).remove();
                    //allSelectBox.splice(i,1);
                } else {
                    $("#div_" + allSelectBox[i]).css({ height: "", width: "" }).hide();
                }
                $(document).unbind("click", killAllBox);
            }
        });
    };

    var _onchange = function (event) {
        var isObj = (event.data.ref instanceof jQuery);
        var $ref = isObj ? event.data.ref : $("#" + event.data.ref);
        if ($ref.size() == 0) return false;
        $.ajax({
            type: "GET", dataType: "json", url: event.data.refUrl.replace("{value}", encodeURIComponent(event.data.$this.attr("value"))), cache: false,
            data: {},
            success: function (json) {
                if (!json) return;
                var html = '';

                $.each(json, function (i) {
                    if (json[i] && json[i].length > 1) {
                        html += '<option value="' + json[i][0] + '">' + json[i][1] + '</option>';
                    }
                });
                var $refselect3 = $ref.parents("div.select3:first");
                $ref.html(html).insertAfter($refselect3);
                $refselect3.remove();
                $ref.trigger("change").select3();
            },
            error: DWZ.ajaxError
        });
    };
    var bingdata = function (event) {
        var isObj = (event.data.ref instanceof jQuery);
        var $ref = isObj ? event.data.ref : $("#" + event.data.ref);
        if ($ref.size() == 0) return false;
        $.ajax({
            dataType: "json", type: "GET", url: event.data.refUrl, cache: false, async: false,
            data: {},
            success: function (json) {
                if (!json) return;
                var html = '';
                //json = json.indexOf("[") == 0 ? json : "[" + json + "]";
                var jsonarr = json;//eval("(" + json + ")");
                var datavalue = $ref.attr("datavalue") || "";
                var datatext = $ref.attr("datatext") || "";
                datavalue = datavalue.substr(0, datavalue.indexOf(":"));
                datatext = datatext.substr(0, datatext.indexOf(":"));
                $.each(jsonarr, function (i) {
                    var index = 0;
                    var val = "";
                    var text = "";
                    var other = "";
                    for (var key in jsonarr[i]) {
                        if (datavalue.length > 0) {
                            if (key == datavalue) val = jsonarr[i][key];
                        }
                        else {
                            if (index == 0) val = jsonarr[i][key];
                        }
                        if (datatext.length > 0) {
                            if (key == datatext) text = jsonarr[i][key];
                        }
                        else {
                            if (index == 1) text = jsonarr[i][key];
                        }
                        if (datavalue.length > 0 && datatext.length > 0) {
                            if (key != datavalue && key != datatext) {
                                other += "" + key + ":'" + jsonarr[i][key] + "',";
                            }
                        }
                        else {
                            if (index > 1) other += "'" + key + "':'" + jsonarr[i][key] + "',";
                        }
                        index++;
                    }
                    if (other && other.length > 0) other = other.substr(0, other.length - 1)
                    html += '<option value="' + val + '" ' + datavalue + '="' + val + '" ' + datatext + '="' + text + '" other="[{' + other + '}]">' + text + '</option>';
                });
                $ref.find(">option").remove();
                $(html).prependTo($ref);
            },
            error: DWZ.ajaxError
        });
    };
    var _selecting = function (options) {
        var index = 0;
        for (var i = 0; i < options.length; i++) {
            if ($(options[i]).hasClass("selected")) {
                index = i;
                break;
            }
        }
        return index;
    };
    var _next = function (options) {
        var max = options.length;
        var next = _selecting(options) + 1;
        return max > next ? $(options[next]) : $(options[0]);
    };
    var _prev = function (options) {
        var max = options.length;
        var prev = _selecting(options) - 1;
        return prev >= 0 ? $(options[prev]) : $(options[max - 1]);
    };

    $.extend($.fn, {
        _select3reposition: function (selector, box) {
            var options = $(this);
            var fwidth = options.width();
            var swidth = selector.width();
            var contextHeight = $("#op_" + box.attr("id")).height();
            if (contextHeight > 5) {
                options.height(contextHeight + 5);
            }
            //options.css("width", swidth > fwidth ? swidth + 25 : fwidth);
            //if (options.is(":hidden")) {
            if (options.height() > 300) {
                options.css({ height: "300px", "overflow-y": "auto" });
            }
            var top = box.offset().top + selector.height();//+box[0].offsetHeight-50;
            if (top + options.height() > $(window).height() - 20) {
                top = box.offset().top - 10 - options.height();
            }
            var left = selector.offset().left;
            if (left + options.width() > $(window).width() - 20) {
                left = selector.offset().left + selector.width() - options.width();
            }
            //alert("options:" + options.height() + ",offset:" + box.offset().top + ",window:" + $(window).height() + ",left:" + selector.offset().left);
            options.css({ top: top, left: left }).show();
            killAllBox(box.attr("id"));
            $(document).click(killAllBox);
            //} else {
            //$(document).unbind("click", killAllBox);
            // killAllBox();
            //}
        },
        select3Select: function (options) {
            var op = $.extend({ selector: ">input" }, options);
            return this.each(function () {
                var box = $(this);
                var selector = $(op.selector, box);
                allSelectBox.push(box.attr("id"));
                var options = $("#div_" + box.attr("id"));
                selector.click(function () {
                    //this.select();
                    if (options.is(":hidden")) {
                        options._select3reposition(selector, box);
                    } else {
                        $(document).unbind("click", killAllBox);
                        killAllBox();
                    }
                    this.select();
                    return false;
                });
                selector.focus(function () {
                    $("#op_" + box.attr("id")).find("tbody>tr").removeAttr("style");
                    selector[0].select();
                });
                selector.focusout(function () {
                    // killAllBox("#div_" + box.attr("id"));
                    $(document).click(killAllBox);
                    //失去焦点后与click事件冲突，因此延迟隐藏
                    //setTimeout(function () { $("#div_" + box.attr("id")).hide(); }, 200);
                });
                selector.attr('autocomplete', 'off');
                selector.keydown(function (evt) {
                    var objfloat = $("#div_" + box.attr("id"));
                    var optionsVisiable = objfloat.find("tbody>tr:visible");
                    switch (evt.keyCode) {
                        case 27://keys.esc:
                            objfloat.hide();
                            //evt.preventDefault();
                            return;
                        case 13://keys.enter:                           
                            /* if ($("#div_" + box.attr("id") + ":visible").length)
                             { options.hide(); }
                             else
                             {
                                 //重设位置
                                 options._select3reposition(selector, box);
                                 options.show();
                             }*/
                            $("#div_" + box.attr("id")).hide();//回车隐藏
                            //输入为空时清空所选
                            if (selector.val() && selector.val.length > 0) {
                                $(".selected", objfloat).selected(selector, box);
                            }
                            else { selector.unselected(box); }
                            evt.preventDefault();
                            return;
                        case 9://keys.tab:
                            $(".selected", objfloat).selected(selector, box);
                            objfloat.hide();
                            //evt.preventDefault();
                            return;
                        case 38://up
                            _prev(optionsVisiable).selected(selector, box);
                            return;
                        case 40://down                            
                            _next(optionsVisiable).selected(selector, box);
                            return;
                    }

                });
                selector.keyup(function (evt) {
                    var divoption = $("#op_" + box.attr("id"));
                    if (evt.keyCode != 40 && evt.keyCode != 38 && evt.keyCode != 9 && evt.keyCode != 27 && evt.keyCode != 13) {
                        divoption.find("tbody>tr").removeAttr("style");
                        divoption.show();
                        var val = selector.val();
                        //if (val.length > 0)
                        {
                            var i = 0;
                            var $input = $("select", box);
                            //计算filter
                            var filtresult = [];
                            if (op.filttype.length > 0 && op.filter.length > 0) {
                                $.each(op.filter.split(','), function (k, c) {
                                    //or条件
                                    c = c.toLowerCase();                                   
                                    if (op.filttype == "or") {
                                        divoption.find("tbody>tr").each(function () {
                                            $tr = $(this);
                                            $tr.find("td").each(function () {
                                                //var $p = $(this).parent();
                                                $(this).filter(" [" + c + "*='" + val + "']").each(function () {                                                   
                                                    filtresult.push($tr);
                                                });
                                            });
                                        });
                                    }
                                    else {//其他方式条件 and等
                                        if (filtresult.length > 0) {
                                            $.grep(filtresult, function (m, e) {
                                                return ($(e).attr(c) || "").indexOf(val) >= 0
                                            });
                                        }
                                        else {//根据 value text 作or 过滤
                                            $.each(divoption.find("tbody>tr").filter("[" + c + "*='" + val + "']"), function (n, e) {
                                                filtresult.push(e);
                                            });
                                        }
                                    }
                                });
                            }
                            else {//根据 value text 作or 过滤
                                divoption.find("tbody>tr").each(function () {
                                    $this = $(this);
                                    if (($this.attr("value").indexOf(val) >= 0 && !op.noValue) || $this.attr("text").indexOf(val) >= 0) {
                                        filtresult.push($this);
                                    }
                                });
                            }

                            //设置是否显示
                            divoption.find("tbody>tr").css("display", "none");
                            $.each(filtresult, function (k, e) {
                                $(e).removeAttr("style");
                            });
                            if (val.length > 0) {
                                //设置选中
                                //$(filtresult[0]).selected(selector, box);
                                var selectsingle = $(filtresult[0]);
                                selectsingle.parent().parent().find(".selected").removeClass("selected");
                                selectsingle.addClass("selected");
                                if (selectsingle.length) {
                                    if ($input.val() != selectsingle.attr("value")) {
                                        $input.val(selectsingle.attr("value")).trigger("change");
                                    }
                                }
                                else {
                                    $input.val("").trigger("change");
                                }
                            } else {
                                $input.val("").trigger("change");
                            }
                            //重设位置
                            $("#div_" + box.attr("id"))._select3reposition(selector, box);

                        }
                    }
                    else if (evt.keyCode == 13) {
                        if (!val || val.length <= 0) {
                            //selector.unselected(box);
                        }
                        /* var tabindex = $(this).parent().find(">select").attr("tabindex");
                         var isfinded = true;
                         while (isfinded) {
                             tabindex += 1;
                             var findobj = $("[tabindex='" + (tabindex) + "']");
                             if (findobj.length > 0) {
                                 if (findobj.hasClass("select_3")) {
                                     findobj = $("[tabindex='" + (tabindex) + "']").parent().find(">input");
                                 }
                                 if (findobj.length > 0) {
                                     findobj.focus();
                                     isfinded = false;
                                     $("#div_" + box.attr("id")).hide();
                                 }
                             }
                         }*/
                    }
                });
                $("#op_" + box.attr("id")).find("tbody").select3Option(selector, box);
            });
        },
        selected: function (selector, box) {
            var $this = $(this);
            $this.parent().parent().find(".selected").removeClass("selected");
            $this.addClass("selected");
            var text = $this.attr("text") || "";
            var val = $this.attr("value") || "";
            selector.val(text);
            var $input = $("select", box);
            if ($this.length) {
                if ($input.val() != val) {
                    $input.val(val).trigger("change");
                }
            }
            else {
                $input.val("").trigger("change");
            }
            selector[0].select();
        },
        unselected: function (box) {
            var $this = $(this);
            $this.val("");
            $this.parent().parent().find(".selected").removeClass("selected");
            var $input = $("select", box);
            if ($input.length) {
                $input.find("option").removeAttr("selected");
                $input.val("");//.trigger("change");
            }
        },
        select3Option: function (selector, box) {
            return this.each(function () {
                $(">tr", this).click(function () {
                    var $this = $(this);
                    $this.selected(selector, box);
                    selector[0].select();
                });
            });
        },
        select3SetEnabled: function () {
            $this = $(this);
            $this.removeAttr("disabled");
            $("#select_" + $this.attr("name")).removeAttr("disabled");
        },
        select3SetDisabled: function () {
            $this = $(this);
            $this.attr("disabled", true);
            $("#select_" + $this.attr("name")).attr("disabled", true);
        },
        select3: function () {
            /* 清理下拉层 */
            var _selectBox = [];

            $.each(allSelectBox, function (i) {
                if ($("#" + allSelectBox[i])[0]) {
                    _selectBox.push(allSelectBox[i]);
                } else {
                    $("#div_" + allSelectBox[i]).remove();
                }
            });
            allSelectBox = _selectBox;

            return this.each(function (i) {
                var $this = $(this).removeClass("select3");
                $this.addClass("select_3");
                //添加一项空选择
                var isempty = $this.find(">option").filter("[value='']").length <= 0;
                if (isempty) {
                    $this.prepend("<option value=\"\"></option>");
                }
                //设置默认选中值
                var defselected = $this.attr("selectedvalue") || "";
                if (defselected.length > 0) $this.val(defselected);
                else $this.val("")

                var name = $this.attr("name");
                var value = $this.val();
                var tabindex = $this.attr("tabindex") || -1;
                var tab = $this.attr("tab") || 1;
                var label = value?$("option[value=" + value + "]", $this).text():"";
                var ref = $this.attr("ref");
                var refUrl = $this.attr("refUrl") || "";
                var columns = $this.attr("columns") || "";
                var datavalue = $this.attr("datavalue") || "";
                var datatext = $this.attr("datatext") || "";
                var vlabel = datavalue.substr(datavalue.indexOf(":") + 1);
                var vtext = datatext.substr(datatext.indexOf(":") + 1);
                var coljson = columns.length > 0 ? eval("(" + columns + ")") : eval([]);
                var filter = $this.attr("filter") || "";
                var filttype = $this.attr("filttype") || "or";
                var valueprop = datavalue.substr(0, datavalue.indexOf(":"));
                var textprop = datatext.substr(0, datatext.indexOf(":"));
                var style = $this.attr("style") || "";
                var disabled = $this.attr("disabled") || "";
                //设置不显示值列
                var noValue = ($this.attr("noValue") ? $this.attr("noValue") : false);
                disabled = disabled && disabled.length ? "disabled='true'" : "";
                $this.removeAttr("disabled");
                //加载ajax数据 
                var ajax = $this.attr("ajax") || "";
                if (ajax.length > 0) {
                    bingdata({ data: { ref: $this, refUrl: ajax } });
                }
                var cid = $this.attr("id") || Math.round(Math.random() * 10000000);
                var select = '<div class="select3" for="' + name + '" rel="div' + name + '"><div id="select3_' + cid + '" class="select"' + (ref ? ' ref="' + ref + '"' : '') + '>';
                select += '<input type="text" class="" style="' + style + '" id="select_' + name + '" name="select_' + name + '" onfocus="this.select()" value="' + label + '" tab="' + tab + '" tabindex="' + tabindex + '"  ' + disabled + '/></div></div>';
                //var options = '<ul class="select3op" id="op_select3_' + cid + '">';
                var options = '<div class="select3op" id="div_select3_' + cid + '">\r\n<table class="list" id="op_select3_' + cid + '">\r\n';
                options += "<thead>";
                options += "<tr>";
                if (!noValue) {
                    options += "<th class='nowrap'>" + vlabel + "</th>";
                }
                options += "<th class='nowrap'>" + vtext + "</th>";
                if (coljson.length > 0) {
                    for (var i = 0; i < coljson.length; i++) {
                        for (var key in coljson[i]) {
                            options += "<th class='nowrap'>" + coljson[i][key] + "</th>";
                        }
                    }
                }
                options += " </tr>";
                options += " </thead>\r\n";
                options += " <tbody>\r\n";
                $("option", $this).each(function () {
                    var option = $(this);
                    if (option.attr("value") && option.attr("value").length > 0) {
                        var others = option.attr("other") || "";
                        var itemid = option.attr("data-tt-id");
                        var treetableCol = "";
                        if (itemid) {
                            var itemParentid = option.attr("data-tt-parent-id");
                            treetableCol = 'data-tt-id="' + itemid + '" data-tt-parent-id="' + itemParentid + '" ';
                        }
                        var valPropCol = ""
                        if (valueprop) {
                            valPropCol = valueprop + '="' + option.attr(valueprop) + '"';
                        }
                        var textPropCol = ""
                        if (textprop) {
                            textPropCol = textprop + '="' + option.attr(textprop) + '"';
                        }

                        options += '<tr  class="' + (value == option[0].value ? "selected" : "") + '"  ' + valPropCol + '  ' + textPropCol + '" value="' + option[0].value + '" text="' + option[0].text + '" other="' + others + '" ' + treetableCol + ' >';
                        if (!noValue) { options += "<td class='nowrap' " + valPropCol + ">" + option[0].value + "</td>"; }
                        options += "<td class='nowrap' " + textPropCol + "><a class=\"" + (value == option[0].value ? "selected" : "") + "\" href=\"#\" value=\"" + option[0].value + "\">" + option[0].text + "</a></td>";
                        //options += "<td>" + option[0].text + "</td>";
                       for (var i = 0; i < coljson.length; i++) {
                        if (coljson.length > 0) {
                            //var ojson = others.length > 0 ? eval("(" + others + ")") : eval([]);
                            var ojson = others.length > 0 ? eval("(" + others + ")") : eval([]);
                                for (var key in coljson[i]) {
                                    var prot = key + "='" + ojson[0][key] + "'";
                                    options += "<td class='nowrap' " + prot + ">" + ojson[0][key] + "</td>";
                                }
                            }
                        }
                        options += "</tr>\r\n";
                    }
                });
                //options += "</ul>";
                options += " </tbody>\r\n";
                options += " </table></div>";

                $("body").append(options);
                $this.after(select);
                $("div.select", $this.next()).select3Select({ filter: filter, filttype: filttype, noValue: noValue }).append($this);
                $("#op_select3_" + cid).cssTable();
                if ($this.hasClass("treetable"))
                    $("#op_select3_" + cid).treetable({ expandable: true, initialState: "expanded" });
                //if (ref && refUrl) {
                //$this.unbind("change", _onchange).bind("change", { ref: ref, refUrl: refUrl, $this: $this }, _onchange);
                //}
                $this.trigger("change");

            });
        }
    });
})(jQuery);
